/*
 * SPDX-FileCopyrightText: 2023-2024 Espressif Systems (Shanghai) CO LTD
 *
 * SPDX-License-Identifier: Unlicense OR CC0-1.0
 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "esp_netif.h"
#include "esp_http_server.h"
#include "nvs_flash.h"
#include "led_strip.h"
#include "esp_err.h"
#include "lwip/ip4_addr.h"

// GPIO assignment
#define LED_STRIP_GPIO_PIN  2
// 118个 LED
#define LED_STRIP_LED_COUNT 118
// 每个区域最多8个LED
#define MAX_LEDS_PER_REGION 8
// 最多4个区域64
#define MAX_REGION_COUNT 64

// WiFi配置
#define DEFAULT_SSID      "ESP32C3-LED-Config"
#define DEFAULT_PASSWORD  "12345678"
#define MAX_STA_CONN      4

// LED状态定义
typedef enum {
    LED_CONNECTING,
    LED_CONNECTED,
    LED_ERROR
} led_status_t;

static const char *TAG = "WiFi-Config";

// 全局变量
static led_strip_handle_t led_strip = NULL;
static httpd_handle_t server = NULL;
static EventGroupHandle_t wifi_event_group;
const int WIFI_CONNECTED_BIT = BIT0;

// 颜色配置结构体
typedef struct {
    uint8_t r;
    uint8_t g;
    uint8_t b;
    uint8_t mode;  // 0:单色, 1:彩虹, 2:呼吸, 3:区域循环, 4:区域多选
} led_config_t;

typedef struct {
    int led_indices[MAX_LEDS_PER_REGION]; // 该区域包含的灯珠编号
    int led_count;                        // 该区域灯珠数量
    // 可扩展：区域颜色、模式等
} led_region_t;

const led_region_t regions[MAX_REGION_COUNT] = {
    // 示例区域定义
    { .led_indices = {1}, .led_count = 1 },   // 区域1
    { .led_indices = {2, 3, 7, 8}, .led_count = 4 }, // 区域2
    { .led_indices = {4, 5, 6}, .led_count = 3 }, // 区域3
    { .led_indices = {9}, .led_count = 1 }, // 区域4
    { .led_indices = {10}, .led_count = 1 }, // 区域5
    { .led_indices = {11}, .led_count = 1 }, // 区域6
    { .led_indices = {12, 23}, .led_count = 2 }, // 区域7
    { .led_indices = {13, 21, 34, 48}, .led_count = 4 }, // 区域8
    { .led_indices = {14, 19}, .led_count = 2 }, // 区域9
    { .led_indices = {15}, .led_count = 1 }, // 区域10
    { .led_indices = {16}, .led_count = 1 }, // 区域11
    { .led_indices = {17, 30, 43}, .led_count = 3 }, // 区域12
    { .led_indices = {18}, .led_count = 1 }, // 区域13
    { .led_indices = {20, 33}, .led_count = 2 }, // 区域14
    { .led_indices = {22, 35}, .led_count = 2 }, // 区域15
    { .led_indices = {24}, .led_count = 1 }, // 区域16
    { .led_indices = {25, 38, 39}, .led_count = 3 }, // 区域17
    { .led_indices = {26}, .led_count = 1 }, // 区域18
    { .led_indices = {27}, .led_count = 1 }, // 区域19
    { .led_indices = {28}, .led_count = 1 }, // 区域20
    { .led_indices = {29}, .led_count = 1 }, // 区域21
    { .led_indices = {31, 45}, .led_count = 2 }, // 区域22
    { .led_indices = {32, 47}, .led_count = 2 }, // 区域23
    { .led_indices = {36, 49}, .led_count = 2 }, // 区域24
    { .led_indices = {37, 40}, .led_count = 2 }, // 区域25
    { .led_indices = {41, 50}, .led_count = 2 }, // 区域26
    { .led_indices = {42, 46}, .led_count = 2 }, // 区域27
    { .led_indices = {44, 64}, .led_count = 2 }, // 区域28
    { .led_indices = {51}, .led_count = 1 }, // 区域29
    { .led_indices = {52}, .led_count = 1 }, // 区域30
    { .led_indices = {53, 74}, .led_count = 2 }, // 区域31
    { .led_indices = {54, 55, 56, 57}, .led_count = 4 }, // 区域32
    { .led_indices = {58}, .led_count = 1 }, // 区域33
    { .led_indices = {59}, .led_count = 1 }, // 区域34
    { .led_indices = {60, 61, 62, 63}, .led_count = 4 }, // 区域35
    { .led_indices = {65}, .led_count = 1 }, // 区域36
    { .led_indices = {66}, .led_count = 1 }, // 区域37
    { .led_indices = {67, 68}, .led_count = 2 }, // 区域38
    { .led_indices = {69, 81}, .led_count = 2 }, // 区域39
    { .led_indices = {70, 80, 89, 97}, .led_count = 4 }, // 区域40
    { .led_indices = {71, 79}, .led_count = 2 }, // 区域41
    { .led_indices = {72, 73}, .led_count = 2 }, // 区域42
    { .led_indices = {75}, .led_count = 1 }, // 区域43
    { .led_indices = {77, 78}, .led_count = 2 }, // 区域44
    { .led_indices = {82, 83}, .led_count = 2 }, // 区域45
    { .led_indices = {84, 85, 100}, .led_count = 3 }, // 区域46
    { .led_indices = {86}, .led_count = 1 }, // 区域47
    { .led_indices = {87}, .led_count = 1 }, // 区域48
    { .led_indices = {88}, .led_count = 1 }, // 区域49
    { .led_indices = {90}, .led_count = 1 }, // 区域50
    { .led_indices = {91}, .led_count = 1 }, // 区域51
    { .led_indices = {92}, .led_count = 1 }, // 区域52
    { .led_indices = {76, 93, 94}, .led_count = 3 }, // 区域53
    { .led_indices = {95, 107}, .led_count = 2 }, // 区域54
    { .led_indices = {96, 105}, .led_count = 2 }, // 区域55
    { .led_indices = {98, 103}, .led_count = 2 }, // 区域56
    { .led_indices = {99, 101}, .led_count = 2 }, // 区域57
    { .led_indices = {102}, .led_count = 1 }, // 区域58
    { .led_indices = {104}, .led_count = 1 }, // 区域59
    { .led_indices = {106}, .led_count = 1 }, // 区域60
    { .led_indices = {108}, .led_count = 1 }, // 区域61
    { .led_indices = {109}, .led_count = 1 }, // 区域62
    { .led_indices = {110, 111, 112, 113, 114, 115, 116, 117}, .led_count = 8 }, // 区域63
    { .led_indices = {118}, .led_count = 1 }, // 区域64
};

static led_config_t current_config = {255, 255, 255, 0}; // 默认白色常亮
static int selected_regions[MAX_REGION_COUNT] = {0};
static int selected_region_count = 0;

// HTML颜色配置页面 - 已移除遗忘WiFi按钮，添加WiFi配置按钮和模态框
static const char color_config_html[] = "<!DOCTYPE html>\
<html>\
<head>\
    <meta charset=\"UTF-8\">\
    <title>ESP32-C3 LED颜色配置</title>\
    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\
    <style>\
        body { font-family: Arial; margin: 20px; background-color: #f0f0f0; }\
        .container { max-width: 500px; margin: auto; background: white; padding: 20px; border-radius: 10px; box-shadow: 0 0 10px rgba(0,0,0,0.1); }\
        h1 { color: #333; text-align: center; }\
        .color-picker { margin: 20px 0; }\
        .mode-selector { margin: 20px 0; }\
        label { display: block; margin: 10px 0 5px; font-weight: bold; }\
        input[type=\"color\"], input[type=\"range\"], select, input[type=\"text\"], input[type=\"password\"] { width: 100%; padding: 8px; margin: 5px 0; box-sizing: border-box; }\
        button { width: 48%; padding: 12px; margin: 5px 1%; border: none; border-radius: 4px; cursor: pointer; font-size: 14px; }\
        .apply-btn { background-color: #4CAF50; color: white; }\
        .apply-btn:hover { background-color: #45a049; }\
        .reset-btn { background-color: #f44336; color: white; }\
        .reset-btn:hover { background-color: #da190b; }\
        .wifi-btn { background-color: #2196F3; color: white; }\
        .wifi-btn:hover { background-color: #1976D2; }\
        .color-display { width: 100%; height: 50px; border: 1px solid #ddd; border-radius: 4px; margin: 10px 0; }\
        .status { padding: 10px; margin: 10px 0; border-radius: 4px; text-align: center; }\
        .success { background-color: #d4edda; color: #155724; border: 1px solid #c3e6cb; }\
        .info { background-color: #d1ecf1; color: #0c5460; border: 1px solid #bee5eb; }\
        .error { background-color: #f8d7da; color: #721c24; border: 1px solid #f5c6cb; }\
        /* WiFi配置模态框样式 */\
        .modal { display: none; position: fixed; z-index: 1000; left: 0; top: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.4); }\
        .modal-content { background-color: #fefefe; margin: 15% auto; padding: 20px; border: 1px solid #888; width: 80%; max-width: 400px; border-radius: 10px; }\
        .close { color: #aaa; float: right; font-size: 28px; font-weight: bold; cursor: pointer; }\
        .close:hover { color: #000; }\
        .wifi-info { background-color: #e8f5e8; padding: 10px; margin: 10px 0; border-radius: 4px; }\
    /* 区域多选紧凑样式 */\
    .region-checkboxes { display: flex; flex-direction: column; gap: 2px; }\
    .region-checkbox-row { display: flex; align-items: center; margin-bottom: 2px; }\
    .region-row-label { width: 32px; text-align: right; font-size: 12px; color: #888; margin-right: 4px; flex-shrink: 0; }\
    .region-checkbox { width: 9%; min-width: 0; box-sizing: border-box; display: flex; align-items: center; font-size: 13px; padding: 1px 0; margin-right: 2px; }\
    .region-checkbox input[type=checkbox] { margin-right: 2px; }\
    </style>\
</head>\
<body>\
    <div class=\"container\">\
        <h1>ESP32-C3 LED颜色配置</h1>\
        <div class=\"info\">\
            <p>设备IP: <span id=\"ip-address\">192.168.4.1</span></p>\
            <p>当前模式: <span id=\"current-mode\">单色</span></p>\
        </div>\
        \
        <div class=\"mode-selector\">\
            <label for=\"mode\">LED模式:</label>\
            <select id=\"mode\" onchange=\"updateMode()\">\
                <option value=\"0\">单色常亮</option>\
                <option value=\"1\">彩虹循环</option>\
                <option value=\"2\">呼吸效果</option>\
                <option value=\"3\">区域循环</option>\
                <option value= \"4\">区域多选</option>\
            </select>\
            </select>\
        </div>\
        \
        <div class=\"color-picker\" id=\"color-picker\" style=\"display: block;\">\
            <label for=\"color\">选择颜色:</label>\
            <input type=\"color\" id=\"color\" value=\"#ffffff\">\
            <div class=\"color-display\" id=\"color-display\" style=\"background-color: #ffffff;\"></div>\
        </div>\
        \
        <div id=\"region-multiselect\" style=\"display:none; margin: 20px 0;\">\
            <label>选择区域:</label>\
            <div class=\"region-checkboxes\" id=\"region-checkboxes\"></div>\
        </div>\
        \
        <div style=\"text-align: center;\">\
            <button class=\"apply-btn\" onclick=\"applyConfig()\">应用配置</button>\
            <button class=\"reset-btn\" onclick=\"resetConfig()\">恢复默认</button>\
        </div>\
        \
        <div style=\"text-align: center; margin-top: 15px;\">\
            <button class=\"wifi-btn\" onclick=\"openWiFiConfig()\">WiFi配置</button>\
        </div>\
        \
        <div class=\"status\" id=\"status\" style=\"display: none;\"></div>\
    </div>\
    \
    <!-- WiFi配置模态框 -->\
    <div id=\"wifiModal\" class=\"modal\">\
        <div class=\"modal-content\">\
            <span class=\"close\" onclick=\"closeWiFiConfig()\">&times;</span>\
            <h2>WiFi配置</h2>\
            <div id=\"wifi-status\"></div>\
            <div id=\"wifi-config-form\" style=\"display: none;\">\
                <label for=\"wifi-ssid\">WiFi名称:</label>\
                <input type=\"text\" id=\"wifi-ssid\" placeholder=\"请输入WiFi名称\">\
                <label for=\"wifi-password\">WiFi密码:</label>\
                <input type=\"password\" id=\"wifi-password\" placeholder=\"请输入WiFi密码\">\
                <button class=\"apply-btn\" onclick=\"saveWiFiConfig()\" style=\"width: 100%;\">保存配置</button>\
            </div>\
            <div id=\"wifi-connected-info\" style=\"display: none;\">\
                <div class=\"wifi-info\">\
                    <p><strong>当前已连接到WiFi</strong></p>\
                    <p>SSID: <span id=\"current-ssid\"></span></p>\
                    <p>IP地址: <span id=\"current-wifi-ip\"></span></p>\
                    <p>信号强度: <span id=\"current-rssi\"></span></p>\
                </div>\
                <button class=\"reset-btn\" onclick=\"resetWiFiConfig()\" style=\"width: 100%;\">重置WiFi配置</button>\
            </div>\
        </div>\
    </div>\
    \
    <script>\
        function updateMode() {\
            const mode = document.getElementById('mode').value;\
            const colorPicker = document.getElementById('color-picker');\
            const currentMode = document.getElementById('current-mode');\
            if (mode === '0') {\
                colorPicker.style.display = 'block';\
                currentMode.textContent = '单色';\
            } else if (mode === '1') {\
                colorPicker.style.display = 'none';\
                currentMode.textContent = '彩虹';\
            } else if (mode === '2') {\
                colorPicker.style.display = 'block';\
                currentMode.textContent = '呼吸';\
            } else if (mode === '3') {\
                colorPicker.style.display = 'block';\
                currentMode.textContent = '区域循环';\
            }\
        }\
        \
        function updateColorDisplay() {\
            const color = document.getElementById('color').value;\
            document.getElementById('color-display').style.backgroundColor = color;\
        }\
        \
        async function applyConfig() {\
            const mode = parseInt(document.getElementById('mode').value);\
            const color = document.getElementById('color').value;\
            const r = parseInt(color.substr(1, 2), 16);\
            const g = parseInt(color.substr(3, 2), 16);\
            const b = parseInt(color.substr(5, 2), 16);\
            \
            try {\
                const response = await fetch('/set-color', {\
                    method: 'POST',\
                    headers: { 'Content-Type': 'application/json' },\
                    body: JSON.stringify({ r, g, b, mode })\
                });\
                const result = await response.json();\
                \
                const status = document.getElementById('status');\
                status.className = 'status success';\
                status.textContent = result.message || '配置已应用！';\
                status.style.display = 'block';\
                \
                setTimeout(() => { status.style.display = 'none'; }, 3000);\
            } catch (error) {\
                const status = document.getElementById('status');\
                status.className = 'status error';\
                status.textContent = '应用失败: ' + error.message;\
                status.style.display = 'block';\
            }\
        }\
        \
        async function resetConfig() {\
            try {\
                await fetch('/reset-color', { method: 'POST' });\
                document.getElementById('color').value = '#ffffff';\
                document.getElementById('mode').value = '0';\
                updateMode();\
                updateColorDisplay();\
                \
                const status = document.getElementById('status');\
                status.className = 'status success';\
                status.textContent = '已恢复默认设置！';\
                status.style.display = 'block';\
                \
                setTimeout(() => { status.style.display = 'none'; }, 3000);\
            } catch (error) {\
                console.error('重置失败:', error);\
            }\
        }\
        \
        async function loadCurrentConfig() {\
            try {\
                const response = await fetch('/get-color');\
                const config = await response.json();\
                \
                document.getElementById('color').value = `#${config.r.toString(16).padStart(2, '0')}${config.g.toString(16).padStart(2, '0')}${config.b.toString(16).padStart(2, '0')}`;\
                document.getElementById('mode').value = config.mode;\
                updateMode();\
                updateColorDisplay();\
            } catch (error) {\
                console.error('加载配置失败:', error);\
            }\
        }\
        \
        async function getIPAddress() {\
            try {\
                const response = await fetch('/ip');\
                const data = await response.json();\
                document.getElementById('ip-address').textContent = data.ip || '获取失败';\
            } catch (error) {\
                document.getElementById('ip-address').textContent = '获取失败';\
            }\
        }\
        \
        function openWiFiConfig() {\
            document.getElementById('wifiModal').style.display = 'block';\
            loadWiFiConfig();\
        }\
        \
        function closeWiFiConfig() {\
            document.getElementById('wifiModal').style.display = 'none';\
        }\
        \
        async function loadWiFiConfig() {\
            try {\
                const response = await fetch('/wifi-status');\
                const data = await response.json();\
                const statusDiv = document.getElementById('wifi-status');\
                const configForm = document.getElementById('wifi-config-form');\
                const connectedInfo = document.getElementById('wifi-connected-info');\
                \
                if (data.connected) {\
                    document.getElementById('current-ssid').textContent = data.ssid || '未知';\
                    document.getElementById('current-wifi-ip').textContent = data.ip || '获取失败';\
                    document.getElementById('current-rssi').textContent = data.rssi ? data.rssi + ' dBm' : '未知';\
                    \
                    configForm.style.display = 'none';\
                    connectedInfo.style.display = 'block';\
                    statusDiv.innerHTML = '<div class=\"wifi-info\"><strong>已连接到WiFi网络</strong></div>';\
                } else {\
                    configForm.style.display = 'block';\
                    connectedInfo.style.display = 'none';\
                    statusDiv.innerHTML = '<div class=\"error\"><strong>未连接到WiFi网络</strong><br>请输入WiFi信息进行配置</div>';\
                }\
            } catch (error) {\
                console.error('获取WiFi状态失败:', error);\
            }\
        }\
        \
        async function saveWiFiConfig() {\
            const ssid = document.getElementById('wifi-ssid').value.trim();\
            const password = document.getElementById('wifi-password').value.trim();\
            \
            if (!ssid) {\
                alert('请输入WiFi名称！');\
                return;\
            }\
            \
            if (confirm(`确定要连接到WiFi \"${ssid}\" 吗？`)) {\
                try {\
                    const response = await fetch('/set-wifi', {\
                        method: 'POST',\
                        headers: { 'Content-Type': 'application/json' },\
                        body: JSON.stringify({ ssid: ssid, password: password })\
                    });\
                    const result = await response.json();\
                    \
                    if (result.status === 'success') {\
                        alert(result.message || 'WiFi配置已保存，设备将重启...');\
                        closeWiFiConfig();\
                    } else {\
                        alert('配置失败: ' + (result.message || '未知错误'));\
                    }\
                } catch (error) {\
                    alert('保存配置失败: ' + error.message);\
                }\
            }\
        }\
        \
        async function resetWiFiConfig() {\
            if (confirm('确定要重置WiFi配置吗？设备将重启并进入配网模式。')) {\
                try {\
                    const response = await fetch('/forget-wifi', { method: 'POST' });\
                    const result = await response.json();\
                    \
                    alert(result.message || 'WiFi配置已重置，设备将重启...');\
                    closeWiFiConfig();\
                } catch (error) {\
                    alert('重置失败: ' + error.message);\
                }\
            }\
        }\
        \
        function updateMode() {\
            const mode = document.getElementById('mode').value;\
            const colorPicker = document.getElementById('color-picker');\
            const currentMode = document.getElementById('current-mode');\
            const regionMulti = document.getElementById('region-multiselect');\
            if (mode === '4') {\
                colorPicker.style.display = 'block';\
                regionMulti.style.display = 'block';\
                currentMode.textContent = '区域多选';\
                renderRegionCheckboxes();\
                loadSelectedRegions();\
            } else {\
                /* ...原有逻辑... */\
                regionMulti.style.display = 'none';\
            }\
        }\
        function renderRegionCheckboxes() {\
            const container = document.getElementById('region-checkboxes');\
            container.innerHTML = '';\
            const total = 64;\
            const perRow = 10;\
            const rows = Math.ceil(total / perRow);\
            for (let row = 0; row < rows; row++) {\
                const rowDiv = document.createElement('div');\
                rowDiv.className = 'region-checkbox-row';\
                const label = document.createElement('span');\
                label.className = 'region-row-label';\
                label.textContent = (row * perRow + 1) + '-' + Math.min((row + 1) * perRow, total);\
                rowDiv.appendChild(label);\
                for (let col = 0; col < perRow; col++) {\
                    const idx = row * perRow + col;\
                    if (idx >= total) break;\
                    const div = document.createElement('div');\
                    div.className = 'region-checkbox';\
                    div.innerHTML = `<input type='checkbox' class='region-cb' value='${idx}'>${idx+1}`;\
                    rowDiv.appendChild(div);\
                }\
                container.appendChild(rowDiv);\
            }\
            document.querySelectorAll('.region-cb').forEach(cb => {\
                cb.addEventListener('change', onRegionChange);\
            });\
        }\
        function onRegionChange() {\
            const checked = Array.from(document.querySelectorAll('.region-cb:checked')).map(cb => parseInt(cb.value));\
            fetch('/set-regions', {\
                method: 'POST',\
                headers: { 'Content-Type': 'application/json' },\
                body: JSON.stringify({ regions: checked })\
            });\
        }\
        async function loadSelectedRegions() {\
            try {\
                const resp = await fetch('/get-regions');\
                const data = await resp.json();\
                document.querySelectorAll('.region-cb').forEach(cb => {\
                    cb.checked = data.regions.includes(parseInt(cb.value));\
                });\
            } catch (e) {}\
        }\
        // 点击模态框外部关闭\
        window.onclick = function(event) {\
            const modal = document.getElementById('wifiModal');\
            if (event.target === modal) {\
                closeWiFiConfig();\
            }\
        }\
        \
        document.getElementById('color').addEventListener('input', updateColorDisplay);\
        \
        // 页面加载时初始化\
        window.onload = function() {\
            loadCurrentConfig();\
            getIPAddress();\
        };\
    </script>\
</body>\
</html>";

// WiFi事件处理函数
static void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        ESP_LOGI(TAG, "WiFi disconnected, retrying...");
        esp_wifi_connect();
        xEventGroupClearBits(wifi_event_group, WIFI_CONNECTED_BIT);
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
        xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

// LED状态设置函数
static void set_led_status(led_status_t status) {
    switch (status) {
        case LED_CONNECTING:
            // 蓝色闪烁表示连接中
            led_strip_set_pixel(led_strip, 0, 0, 0, 255);
            led_strip_refresh(led_strip);
            vTaskDelay(pdMS_TO_TICKS(200));
            led_strip_set_pixel(led_strip, 0, 0, 0, 0);
            led_strip_refresh(led_strip);
            vTaskDelay(pdMS_TO_TICKS(200));
            break;
        case LED_CONNECTED:
            // 绿色常亮表示已连接
            led_strip_set_pixel(led_strip, 0, 0, 255, 0);
            led_strip_refresh(led_strip);
            break;
        case LED_ERROR:
            // 红色闪烁表示错误
            led_strip_set_pixel(led_strip, 0, 255, 0, 0);
            led_strip_refresh(led_strip);
            vTaskDelay(pdMS_TO_TICKS(500));
            led_strip_set_pixel(led_strip, 0, 0, 0, 0);
            led_strip_refresh(led_strip);
            vTaskDelay(pdMS_TO_TICKS(500));
            break;
    }
}

// 颜色控制相关函数
static void save_color_config(led_config_t *config) {
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("led_config", NVS_READWRITE, &nvs_handle);
    if (err == ESP_OK) {
        nvs_set_u8(nvs_handle, "r", config->r);
        nvs_set_u8(nvs_handle, "g", config->g);
        nvs_set_u8(nvs_handle, "b", config->b);
        nvs_set_u8(nvs_handle, "mode", config->mode);
        nvs_commit(nvs_handle);
        nvs_close(nvs_handle);
    }
}

static void load_color_config(led_config_t *config) {
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("led_config", NVS_READONLY, &nvs_handle);
    if (err == ESP_OK) {
        nvs_get_u8(nvs_handle, "r", &config->r);
        nvs_get_u8(nvs_handle, "g", &config->g);
        nvs_get_u8(nvs_handle, "b", &config->b);
        nvs_get_u8(nvs_handle, "mode", &config->mode);
        nvs_close(nvs_handle);
    } else {
        // 默认值
        config->r = 255;
        config->g = 255;
        config->b = 255;
        config->mode = 0;
    }
}

// 应用LED配置
static void apply_led_config() {
    switch (current_config.mode) {
        case 0: // 单色常亮
            for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
                led_strip_set_pixel(led_strip, i, current_config.r, current_config.g, current_config.b);
            }
            led_strip_refresh(led_strip);
            break;
        case 1: // 彩虹循环 - 在循环中处理
            break;
        case 2: // 呼吸效果 - 在循环中处理
            break;
        case 3: // 区域依次循环点亮
            // 这里不做具体显示，主循环处理
            break;
    }
}

// 保存WiFi配置到NVS
static void save_wifi_config(const char* ssid, const char* password) {
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("wifi_config", NVS_READWRITE, &nvs_handle);
    if (err == ESP_OK) {
        nvs_set_str(nvs_handle, "ssid", ssid);
        nvs_set_str(nvs_handle, "password", password);
        nvs_commit(nvs_handle);
        nvs_close(nvs_handle);
        ESP_LOGI(TAG, "WiFi configuration saved to NVS");
    }
}

// 从NVS加载WiFi配置
static bool load_wifi_config(char* ssid, size_t ssid_len, char* password, size_t password_len) {
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("wifi_config", NVS_READONLY, &nvs_handle);
    if (err == ESP_OK) {
        if (nvs_get_str(nvs_handle, "ssid", ssid, &ssid_len) == ESP_OK &&
            nvs_get_str(nvs_handle, "password", password, &password_len) == ESP_OK) {
            nvs_close(nvs_handle);
            ESP_LOGI(TAG, "Loaded WiFi config: SSID=%s", ssid);
            return true;
        }
        nvs_close(nvs_handle);
    }
    return false;
}

// HTTP API处理函数
static esp_err_t color_config_get_handler(httpd_req_t *req) {
    httpd_resp_set_type(req, "text/html");
    return httpd_resp_send(req, color_config_html, strlen(color_config_html));
}

static esp_err_t set_color_handler(httpd_req_t *req) {
    char content[128];
    size_t recv_size = MIN(req->content_len, sizeof(content) - 1);
    
    int ret = httpd_req_recv(req, content, recv_size);
    if (ret <= 0) {
        return ESP_FAIL;
    }
    content[ret] = '\0';
    
    // 添加CORS头
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "POST, OPTIONS");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
    
    // 处理OPTIONS预检请求
    if (req->method == HTTP_OPTIONS) {
        return httpd_resp_send(req, NULL, 0);
    }
    
    // 解析JSON
    int r, g, b, mode;
    if (sscanf(content, "{\"r\":%d,\"g\":%d,\"b\":%d,\"mode\":%d}", &r, &g, &b, &mode) == 4) {
        current_config.r = (uint8_t)r;
        current_config.g = (uint8_t)g;
        current_config.b = (uint8_t)b;
        current_config.mode = (uint8_t)mode;
        
        save_color_config(&current_config);
        apply_led_config();
        
        const char *response = "{\"status\":\"success\",\"message\":\"配置已应用\"}";
        httpd_resp_set_type(req, "application/json");
        return httpd_resp_send(req, response, strlen(response));
    }
    
    const char *error_response = "{\"status\":\"error\",\"message\":\"参数错误\"}";
    httpd_resp_set_type(req, "application/json");
    return httpd_resp_send(req, error_response, strlen(error_response));
}

static esp_err_t get_color_handler(httpd_req_t *req) {
    // 添加CORS头
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "GET");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
    
    char response[128];
    snprintf(response, sizeof(response), "{\"r\":%d,\"g\":%d,\"b\":%d,\"mode\":%d}", 
            current_config.r, current_config.g, current_config.b, current_config.mode);
    
    httpd_resp_set_type(req, "application/json");
    return httpd_resp_send(req, response, strlen(response));
}

static esp_err_t reset_color_handler(httpd_req_t *req) {
    // 添加CORS头
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "POST, OPTIONS");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
    
    // 处理OPTIONS预检请求
    if (req->method == HTTP_OPTIONS) {
        return httpd_resp_send(req, NULL, 0);
    }
    
    current_config.r = 255;
    current_config.g = 255;
    current_config.b = 255;
    current_config.mode = 0;
    
    save_color_config(&current_config);
    apply_led_config();
    
    const char *response = "{\"status\":\"success\",\"message\":\"已重置为默认\"}";
    httpd_resp_set_type(req, "application/json");
    return httpd_resp_send(req, response, strlen(response));
}

static esp_err_t get_ip_handler(httpd_req_t *req) {
    // 处理OPTIONS预检请求
    if (req->method == HTTP_OPTIONS) {
        httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
        httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "GET, OPTIONS");
        httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type, Authorization");
        return httpd_resp_send(req, NULL, 0);
    }
    
    // 添加完整的CORS头
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "GET, OPTIONS");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type, Authorization");
    httpd_resp_set_hdr(req, "Cache-Control", "no-cache, no-store, must-revalidate");
    
    esp_netif_ip_info_t ip_info;
    char response[64];
    
    // 首先尝试获取AP模式的IP（因为当前运行在AP模式）
    esp_netif_t *netif_ap = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
    if (netif_ap && esp_netif_get_ip_info(netif_ap, &ip_info) == ESP_OK) {
        snprintf(response, sizeof(response), "{\"ip\":\"%d.%d.%d.%d\"}", 
                IP2STR(&ip_info.ip));
        httpd_resp_set_type(req, "application/json");
        return httpd_resp_send(req, response, strlen(response));
    }
    
    // 如果AP模式没有IP，尝试获取STA模式的IP
    esp_netif_t *netif_sta = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
    if (netif_sta && esp_netif_get_ip_info(netif_sta, &ip_info) == ESP_OK) {
        if (ip_info.ip.addr != 0) {
            snprintf(response, sizeof(response), "{\"ip\":\"%d.%d.%d.%d\"}", 
                    IP2STR(&ip_info.ip));
            httpd_resp_set_type(req, "application/json");
            return httpd_resp_send(req, response, strlen(response));
        }
    }
    
    // 如果都失败了，返回已知的AP模式IP（根据日志）
    snprintf(response, sizeof(response), "{\"ip\":\"192.168.4.1\"}");
    httpd_resp_set_type(req, "application/json");
    return httpd_resp_send(req, response, strlen(response));
}

// 获取WiFi状态处理器
static esp_err_t wifi_status_handler(httpd_req_t *req) {
    // 添加CORS头
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "GET");
    
    wifi_ap_record_t ap_info;
    esp_netif_ip_info_t ip_info;
    esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
    
    char response[256];
    bool connected = false;
    const char* ssid = "";
    char ip_str[16] = "0.0.0.0";  // 移到这里并初始化
    const char* ip = ip_str;      // 指向ip_str
    int rssi = 0;
    
    if (esp_wifi_sta_get_ap_info(&ap_info) == ESP_OK) {
        connected = true;
        ssid = (const char*)ap_info.ssid;
        rssi = ap_info.rssi;
        
        if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) {
            snprintf(ip_str, sizeof(ip_str), "%d.%d.%d.%d", IP2STR(&ip_info.ip));
        }
    }
    
    snprintf(response, sizeof(response), 
            "{\"connected\":%s,\"ssid\":\"%s\",\"ip\":\"%s\",\"rssi\":%d}", 
            connected ? "true" : "false", ssid, ip, rssi);
    
    httpd_resp_set_type(req, "application/json");
    return httpd_resp_send(req, response, strlen(response));
}

// 设置WiFi配置处理器
static esp_err_t set_wifi_handler(httpd_req_t *req) {
    // 添加CORS头
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "POST, OPTIONS");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
    
    // 处理OPTIONS预检请求
    if (req->method == HTTP_OPTIONS) {
        return httpd_resp_send(req, NULL, 0);
    }
    
    char content[256];
    size_t recv_size = MIN(req->content_len, sizeof(content) - 1);
    
    int ret = httpd_req_recv(req, content, recv_size);
    if (ret <= 0) {
        return ESP_FAIL;
    }
    content[ret] = '\0';
    
    // 解析JSON
    char ssid[33] = {0};
    char password[65] = {0};
    
    // 简单的JSON解析
    char *ssid_start = strstr(content, "\"ssid\":\"");
    char *password_start = strstr(content, "\"password\":\"");
    
    if (ssid_start && password_start) {
        ssid_start += 8; // 跳过"ssid":"
        char *ssid_end = strchr(ssid_start, '\"');
        if (ssid_end && (ssid_end - ssid_start) < sizeof(ssid) - 1) {
            strncpy(ssid, ssid_start, ssid_end - ssid_start);
            ssid[ssid_end - ssid_start] = '\0';
        }
        
        password_start += 12; // 跳过"password":"
        char *password_end = strrchr(password_start, '\"');
        if (password_end && (password_end - password_start) < sizeof(password) - 1) {
            strncpy(password, password_start, password_end - password_start);
            password[password_end - password_start] = '\0';
        }
        
        if (strlen(ssid) > 0) {
            // 保存配置到NVS
            save_wifi_config(ssid, password);
            
            const char *response = "{\"status\":\"success\",\"message\":\"WiFi配置已保存，设备将重启并连接到新网络\"}";
            httpd_resp_set_type(req, "application/json");
            return httpd_resp_send(req, response, strlen(response));
        }
    }
    
    const char *error_response = "{\"status\":\"error\",\"message\":\"无效的WiFi配置参数\"}";
    httpd_resp_set_type(req, "application/json");
    return httpd_resp_send(req, error_response, strlen(error_response));
}

// 忘记WiFi处理器
static esp_err_t forget_wifi_handler(httpd_req_t *req) {
    // 添加CORS头
    httpd_resp_set_hdr(req, "Access-Control-Allow-Origin", "*");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Methods", "POST");
    httpd_resp_set_hdr(req, "Access-Control-Allow-Headers", "Content-Type");
    
    // 处理OPTIONS预检请求
    if (req->method == HTTP_OPTIONS) {
        return httpd_resp_send(req, NULL, 0);
    }
    
    // 删除保存的WiFi配置
    nvs_handle_t nvs_handle;
    esp_err_t err = nvs_open("wifi_config", NVS_READWRITE, &nvs_handle);
    
    if (err == ESP_OK) {
        // 删除WiFi配置键值
        nvs_erase_key(nvs_handle, "ssid");
        nvs_erase_key(nvs_handle, "password");
        nvs_commit(nvs_handle);
        nvs_close(nvs_handle);
        
        ESP_LOGI(TAG, "WiFi configuration erased from NVS");
        
        const char *response = "{\"status\":\"success\",\"message\":\"WiFi配置已删除，设备将重启\"}";
        httpd_resp_set_type(req, "application/json");
        return httpd_resp_send(req, response, strlen(response));
    } else {
        ESP_LOGE(TAG, "Failed to open NVS for WiFi config: %s", esp_err_to_name(err));
        const char *response = "{\"status\":\"error\",\"message\":\"删除WiFi配置失败\"}";
        httpd_resp_set_type(req, "application/json");
        return httpd_resp_send(req, response, strlen(response));
    }
}

// 区域多选API：设置选中区域
static esp_err_t set_regions_handler(httpd_req_t *req) {
    char buf[512];
    int ret = httpd_req_recv(req, buf, sizeof(buf)-1);
    if (ret <= 0) return ESP_FAIL;
    buf[ret] = '\0';
    // 解析JSON: {"regions":[0,2,5,...]}
    int count = 0;
    int tmp[MAX_REGION_COUNT] = {0};
    char *p = strstr(buf, "[");
    char *q;
    if (p) {
        p++;
        while ((q = strchr(p, ',')) || (q = strchr(p, ']'))) {
            int idx = 0;
            if (sscanf(p, "%d", &idx) == 1 && idx >= 0 && idx < MAX_REGION_COUNT && count < MAX_REGION_COUNT) {
                tmp[count++] = idx;
            }
            if (*q == ']') break;
            p = q+1;
        }
    }
    memcpy(selected_regions, tmp, sizeof(int)*count);
    selected_region_count = count;
    httpd_resp_set_type(req, "application/json");
    httpd_resp_send(req, "{\"status\":\"success\"}", -1);
    return ESP_OK;
}

// 区域多选API：获取当前选中区域
static esp_err_t get_regions_handler(httpd_req_t *req) {
    char buf[1024] = "{\"regions\": [";
    for (int i = 0; i < selected_region_count; i++) {
        char tmp[8];
        snprintf(tmp, sizeof(tmp), "%d%s", selected_regions[i], (i==selected_region_count-1)?"":",");
        strcat(buf, tmp);
    }
    strcat(buf, "]}");
    httpd_resp_set_type(req, "application/json");
    httpd_resp_send(req, buf, -1);
    return ESP_OK;
}

// 启动HTTP服务器
static void start_color_server(void) {
    httpd_config_t config = HTTPD_DEFAULT_CONFIG();
    config.max_uri_handlers = 12;
    
    ESP_LOGI(TAG, "Starting color server on port: %d", config.server_port);
    if (httpd_start(&server, &config) == ESP_OK) {
        // 颜色配置页面
        httpd_uri_t color_config = {
            .uri       = "/",
            .method    = HTTP_GET,
            .handler   = color_config_get_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &color_config);

        // 设置颜色API
        httpd_uri_t set_color = {
            .uri       = "/set-color",
            .method    = HTTP_POST,
            .handler   = set_color_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &set_color);

        // 获取颜色API
        httpd_uri_t get_color = {
            .uri       = "/get-color",
            .method    = HTTP_GET,
            .handler   = get_color_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &get_color);

        // 重置颜色API
        httpd_uri_t reset_color = {
            .uri       = "/reset-color",
            .method    = HTTP_POST,
            .handler   = reset_color_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &reset_color);

        // 获取IP地址API
        httpd_uri_t get_ip = {
            .uri       = "/ip",
            .method    = HTTP_GET,
            .handler   = get_ip_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &get_ip);

        // 忘记WiFi API
        httpd_uri_t forget_wifi = {
            .uri       = "/forget-wifi",
            .method    = HTTP_POST,
            .handler   = forget_wifi_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &forget_wifi);

        // 获取WiFi状态API
        httpd_uri_t wifi_status = {
            .uri       = "/wifi-status",
            .method    = HTTP_GET,
            .handler   = wifi_status_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &wifi_status);

        // 设置WiFi配置API
        httpd_uri_t set_wifi = {
            .uri       = "/set-wifi",
            .method    = HTTP_POST,
            .handler   = set_wifi_handler,
            .user_ctx  = NULL
        };
        httpd_register_uri_handler(server, &set_wifi);

        // 区域多选API
        httpd_uri_t set_regions = {
            .uri = "/set-regions",
            .method = HTTP_POST,
            .handler = set_regions_handler,
            .user_ctx = NULL
        };
        httpd_register_uri_handler(server, &set_regions);

        httpd_uri_t get_regions = {
            .uri = "/get-regions",
            .method = HTTP_GET,
            .handler = get_regions_handler,
            .user_ctx = NULL
        };
        httpd_register_uri_handler(server, &get_regions);

        ESP_LOGI(TAG, "Color server started successfully");
    } else {
        ESP_LOGE(TAG, "Failed to start color server");
    }
}

// 初始化WiFi
static void wifi_init_softap(void) {
    ESP_ERROR_CHECK(esp_netif_init());
    //wifi_event_group = xEventGroupCreate();
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_create_default_wifi_ap();

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL));
    ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL));

    wifi_config_t wifi_config = {
        .ap = {
            .ssid = DEFAULT_SSID,
            .ssid_len = strlen(DEFAULT_SSID),
            .channel = 1,
            .password = DEFAULT_PASSWORD,
            .max_connection = MAX_STA_CONN,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
        },
    };
    
    if (strlen(DEFAULT_PASSWORD) == 0) {
        wifi_config.ap.authmode = WIFI_AUTH_OPEN;
    }

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "WiFi softAP started. SSID:%s password:%s", DEFAULT_SSID, DEFAULT_PASSWORD);
}

// 检查是否有保存的WiFi配置并尝试连接
static bool check_saved_wifi_config(void) {
    char ssid[33] = {0};
    char password[65] = {0};
    
    if (load_wifi_config(ssid, sizeof(ssid), password, sizeof(password))) {
        ESP_LOGI(TAG, "Found saved WiFi config, attempting to connect...");
        
        // 创建STA接口
        esp_netif_create_default_wifi_sta();
        
        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_wifi_init(&cfg));
        
        ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &wifi_event_handler, NULL, NULL));
        ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, NULL));
        
        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
        
        wifi_config_t wifi_config = {0};
        strncpy((char*)wifi_config.sta.ssid, ssid, sizeof(wifi_config.sta.ssid));
        strncpy((char*)wifi_config.sta.password, password, sizeof(wifi_config.sta.password));
        wifi_config.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;
        
        ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
        ESP_ERROR_CHECK(esp_wifi_start());
        
        // 等待连接
        EventBits_t bits = xEventGroupWaitBits(wifi_event_group, WIFI_CONNECTED_BIT, pdFALSE, pdTRUE, pdMS_TO_TICKS(10000));
        
        if (bits & WIFI_CONNECTED_BIT) {
            ESP_LOGI(TAG, "Connected to saved WiFi network");
            return true;
        } else {
            ESP_LOGI(TAG, "Failed to connect to saved WiFi, starting softAP");
            esp_wifi_stop();
            return false;
        }
    }
    
    return false;
}

// 初始化LED
led_strip_handle_t configure_led(void) {
    led_strip_config_t strip_config = {
        .strip_gpio_num = LED_STRIP_GPIO_PIN,
        .max_leds = LED_STRIP_LED_COUNT,
        .led_model = LED_MODEL_WS2812,
        .color_component_format = {
            .format = {
                .r_pos = 1,
                .g_pos = 0,
                .b_pos = 2,
                .num_components = 3,
            },
        },
        .flags = {
            .invert_out = false,
        }
    };

    led_strip_spi_config_t spi_config = {
        .clk_src = SPI_CLK_SRC_DEFAULT,
        .spi_bus = SPI2_HOST,
        .flags = {
            .with_dma = true,
        }
    };

    led_strip_handle_t led_strip;
    ESP_ERROR_CHECK(led_strip_new_spi_device(&strip_config, &spi_config, &led_strip));
    ESP_LOGI(TAG, "Created LED strip object with SPI backend");
    return led_strip;
}

// 主函数
void app_main(void) {
    // 初始化NVS
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ESP_ERROR_CHECK(nvs_flash_init());
    }

    // 初始化LED
    led_strip = configure_led();
    
    // 加载保存的颜色配置
    load_color_config(&current_config);
    
    // 初始化WiFi事件组
    wifi_event_group = xEventGroupCreate();
    
    // 尝试连接保存的WiFi，失败则启动SoftAP
    if (!check_saved_wifi_config()) {
        wifi_init_softap();
    }
    set_led_status(LED_CONNECTING);
    // 启动HTTP服务器
    start_color_server();

    // LED状态指示
    while (true) {
        switch (current_config.mode) {
            case 0: // 单色常亮 - 已在apply_led_config中设置
                vTaskDelay(1000 / portTICK_PERIOD_MS);
                break;
            case 1: // 彩虹循环
                for (int hue = 0; hue < 360; hue += 5) {
                    for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
                        int pixel_hue = (hue + i * 360 / LED_STRIP_LED_COUNT) % 360;
                        float r, g, b;
                        // HSV转RGB
                        float s = 1.0f;
                        float v = 1.0f;
                        float c = v * s;
                        float x = c * (1 - fabsf(fmodf(pixel_hue / 60.0f, 2) - 1));
                        float m = v - c;
                        if (pixel_hue < 60) {
                            r = c; g = x; b = 0;
                        } else if (pixel_hue < 120) {
                            r = x; g = c; b = 0;
                        } else if (pixel_hue < 180) {
                            r = 0; g = c; b = x;
                        } else if (pixel_hue < 240) {
                            r = 0; g = x; b = c;
                        } else if (pixel_hue < 300) {
                            r = x; g = 0; b = c;
                        } else {
                            r = c; g = 0; b = x;
                        }
                        led_strip_set_pixel(led_strip, i, 
                                          (uint8_t)((r + m) * 255),
                                          (uint8_t)((g + m) * 255),
                                          (uint8_t)((b + m) * 255));
                    }
                    led_strip_refresh(led_strip);
                    vTaskDelay(50 / portTICK_PERIOD_MS);
                }
                break;
            case 2: // 呼吸效果
                for (int brightness = 0; brightness <= 255; brightness += 5) {
                    for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
                        float factor = brightness / 255.0f;
                        led_strip_set_pixel(led_strip, i,
                                          (uint8_t)(current_config.r * factor),
                                          (uint8_t)(current_config.g * factor),
                                          (uint8_t)(current_config.b * factor));
                    }
                    led_strip_refresh(led_strip);
                    vTaskDelay(20 / portTICK_PERIOD_MS);
                }
                for (int brightness = 255; brightness >= 0; brightness -= 5) {
                    for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
                        float factor = brightness / 255.0f;
                        led_strip_set_pixel(led_strip, i,
                                          (uint8_t)(current_config.r * factor),
                                          (uint8_t)(current_config.g * factor),
                                          (uint8_t)(current_config.b * factor));
                    }
                    led_strip_refresh(led_strip);
                    vTaskDelay(20 / portTICK_PERIOD_MS);
                }
                break;
            case 3: // 区域依次循环点亮
                for (int region = 0; region < MAX_REGION_COUNT; region++) {
                    // 先全部熄灭
                    for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
                        led_strip_set_pixel(led_strip, i, 0, 0, 0);
                    }
                    // 点亮当前区域
                    for (int j = 0; j < regions[region].led_count; j++) {
                        int led_id = regions[region].led_indices[j];
                        if (led_id >= 0 && led_id <= LED_STRIP_LED_COUNT) {
                            led_strip_set_pixel(led_strip, led_id-1, current_config.r, current_config.g, current_config.b);
                        }
                    }
                    led_strip_refresh(led_strip);
                    vTaskDelay(200 / portTICK_PERIOD_MS);
                }
                break;
            case 4: // 区域多选模式
                for (int i = 0; i < LED_STRIP_LED_COUNT; i++) {
                    led_strip_set_pixel(led_strip, i, 0, 0, 0);
                }
                for (int i = 0; i < selected_region_count; i++) {
                    int region = selected_regions[i];
                    if (region >= 0 && region < MAX_REGION_COUNT) {
                        for (int j = 0; j < regions[region].led_count; j++) {
                            int led_id = regions[region].led_indices[j];
                            if (led_id >= 0 && led_id <= LED_STRIP_LED_COUNT) {
                                led_strip_set_pixel(led_strip, led_id-1, current_config.r, current_config.g, current_config.b);
                            }
                        }
                    }
                }
                led_strip_refresh(led_strip);
                vTaskDelay(200 / portTICK_PERIOD_MS);
                break;
        }
    }
}